package com.mkb.conf;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;

public class BusinessExceptionResolver extends SimpleMappingExceptionResolver {
	
	private static final Logger logger = LoggerFactory.getLogger(BusinessExceptionResolver.class);
	private static final List<String> ERROR_TIP = new ArrayList<String>();

	static {
		ERROR_TIP.add("系统出现不可预见异常，请联系管理员......");
	}

	public void setTips(Set<String> tips) {
		ERROR_TIP.addAll(tips);
	}

	public BusinessExceptionResolver addTip(String tip) {
		ERROR_TIP.add(tip);

		return this;
	}

	@Override
	protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
		String msg = e.getMessage();
		
		if (e.getStackTrace().length > 0) {
			StackTraceElement stack = e.getStackTrace()[0];
			String info = "异常[" + e.getClass().getSimpleName() + "]类[" + stack.getClassName() + "]方法[" + stack.getMethodName() + "]行数[" + stack.getLineNumber() + "]";
			
			if (StringUtils.isBlank(msg)) {
				msg = info;
			} else {
				logger.error(info);
			}
		}
		
		e.printStackTrace();
		String viewName = determineViewName(e, request);

		if (viewName != null) { // 传统同步请求
			if (!(request.getHeader("accept").contains("application/json") || (request.getHeader("X-Requested-With") != null && request.getHeader("X-Requested-With").contains("XMLHttpRequest")))) {
				Integer statusCode = determineStatusCode(request, viewName);

				if (statusCode != null) {
					applyStatusCodeIfPossible(request, response, statusCode);
				}

				ModelAndView mv = getModelAndView(viewName, e, request);
				mv.addObject("msg", msg);
				mv.addObject("msgTip", ERROR_TIP.get(new Random().nextInt(ERROR_TIP.size())));
				
				return mv;
			} else { // AJAX异步请求
				try {
					response.setCharacterEncoding("utf-8");
					PrintWriter writer = response.getWriter();
					response.setContentType("text/json; charset=utf-8");
					writer.write(e.getMessage());
					writer.flush();
					writer.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				
				return null;
			}
		} else {
			return null;
		}
	}
	
}